home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------------
- #
- # Apple Developer Technical Support
- #
- # OtherResInfo
- # Answering the perenial question....
- # How can I mess around in someone else's resource fork
- # without getting their resources in my chain?
- #
- # OtherResInfo.c - C Source
- #
- # Copyright © 1992 Apple Computer, Inc.
- # All rights reserved.
- #
- # Versions:
- # 1.0 12/92 C.K. Haun <TR>
- # Here's one nice System 7 way.
- # I use a seperate, background-only application to do the actual manipulation
- # of the resource fork of the other application.
- # The backgrounder tells the foreground app what it's found with AppleEvents.
- # The backgrounder has (runtime-wise) only one resource to care about, it's
- # Main code segement, so it is never worried about pulling in any stray
- # resources from the other resource fork.
- # Also, since you can have the backgrounder quit right after it does it's work, you
- # do not need to worry about "Should I close the other resource fork,
- # was it already open, has it been opened since I started working" and so on.
- # By having the backgrounder quit, you're letting the Process Manager
- # worry about keeping the resource fork open, not you.
- #
- # And anyway, it's a nice demo of how you can use a background-only app to do dirty work for you.
- # Written by C.K. Haun <TR>
- # Apple Developer Tech Support
- # Of course, Copyright 1992, Apple Computer Inc.
- # ---------------------------------------------------------------
- # Use this sample as a starting point, and adapt its' routines to
- # meet the specific needs of your project.
- # This sample will grow as more edition types are implemented,
- # periodically check AppleLink for a later, expanded sample.
- # This application is an example of the form of a Macintosh
- # application; it is NOT a template. It is NOT intended to be
- # used as a foundation for the next world-class, best-selling,
- # 600K application. A stick figure drawing of the human body may
- # be a good example of the form for a painting, but that does not
- # mean it should be used as the basis for the next Mona Lisa.
- #
- #
- ------------------------------------------------------------------------------*/
-
- #include "OtherResInfo.h"
-
- /* globals */
- Boolean gQuit, gInBackground;
- unsigned long gMySleep=kFrontSleep; /* I don't need to take up a lot of time when I'm frontmost */
- ProcessSerialNumber gOurSN;
-
- short gHelpItem;
- extraDialogFilter gExtraDialogFilter;
-
-
-
- #pragma segment Main
-
-
-
- main()
- {
- EventRecord myEventRecord;
- WindowPtr twindow;
- short fHit;
- windowCHandle tempWCH;
-
- UnloadSeg((Ptr)_DataInit); /* throw out setup code */
- InitalizeApp();
- UnloadSeg((Ptr)InitalizeApp); /* get rid of my initialization code */
- do {
-
- WaitNextEvent(everyEvent, &myEventRecord, gMySleep, nil);
-
- switch (myEventRecord.what) {
-
- case nullEvent:
- /* no nul processing in this sample */
- break;
-
- case updateEvt:
- /* always check to see if it's my window */
- /* this may not seem necessary under 7.0, where it's unlikely or impossible for */
- /* a DA to be in your layer, but there are others */
- /* who can stick themselves into your window list, */
- /* BalloonWriter comes quickly to mind */
- if (IsMyWindow((WindowPtr)myEventRecord.message)) {
- tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message);
- ((*tempWCH)->drawMe)((WindowPtr)myEventRecord.message);
- }
- break;
-
- case mouseDown:
- /* first see where the hit was */
- fHit = FindWindow(myEventRecord.where, &twindow);
- switch (fHit) {
- Rect limitRect;
- Str255 tempString;
- long back;
-
- case inDesk: /* if they hit in desk, then the process manager */
- break; /* will switch us out, we don't need to do anything */
-
- case inMenuBar:
- AdjustMenus();
- DoSelected(MenuSelect(myEventRecord.where));
- break;
-
- case inSysWindow:
- /* pass to the system */
- SystemClick(&myEventRecord, twindow);
- break;
-
- case inContent:
- /* Handle content and control clicks here */
- if (FrontWindow()==twindow) { /* don't do this unless we have a window open, silly */
- windowCHandle clicker;
- clicker = (windowCHandle)GetWRefCon(twindow);
- /* jump to the content function stored for this window */
- HLock((Handle)clicker); /* lock it down so things don't get stupid */
- ((*clicker)->clickMe)(twindow);
- HUnlock((Handle)clicker); /* all done */
- } else {
- /* bring this window forward */
- SelectWindow(twindow); /* select the window */
- SetPort(twindow);
-
- }
- break;
-
- case inDrag:
- DragWindow(twindow, myEventRecord.where, &qd.screenBits.bounds);
- break;
-
- case inGrow:
- /* Call GrowWindow here if you have a grow box */
-
- SetPort(twindow);
- limitRect = qd.screenBits.bounds;
- limitRect.top = kMinHeight;
-
-
- /* I'm not letting the user shrink the window so */
- /* small that the title is truncated */
- /* grab the title of the window */
- GetWTitle(twindow, tempString);
- /* make the limit the length of the title plus some */
- /* padding for the close box and zoom box */
- limitRect.left = StringWidth(tempString) + kWindowBarPad;
-
- back = GrowWindow(twindow, myEventRecord.where, &limitRect);
-
- if (back) {
-
- Rect sizeRect = ((WindowPtr)twindow)->portRect;
-
- tempWCH = (windowCHandle)GetWRefCon(twindow);
- InvalRect(&sizeRect);
- sizeRect.top = sizeRect.bottom - kScrollBarFudge;
- sizeRect.left = sizeRect.right - kScrollBarFudge;
- EraseRect(&sizeRect);
- InvalRect(&sizeRect);
- SizeWindow(twindow, back & 0xffff, back >> kScrollBarFudge, true);
- ((*tempWCH)->sizeMe)(twindow);
- }
-
- InvalRect(&twindow->portRect);
-
- break;
-
- case inGoAway:
-
- /* Click in Close box */
-
- if (TrackGoAway(twindow, myEventRecord.where)){
- tempWCH = (windowCHandle)GetWRefCon(twindow);
-
- ((*tempWCH)->closeMe)(twindow);
- }
- break;
-
- case inZoomIn:
- case inZoomOut:
- /* Who's Zooming Who? (sorry) */
- if (TrackBox(twindow, myEventRecord.where, fHit)) {
- tempWCH = (windowCHandle)GetWRefCon(twindow);
- SetPort(twindow);
-
- ZoomWindow(twindow, fHit, true);
- EraseRect(&twindow->portRect);
- InvalRect(&twindow->portRect);
- ((*tempWCH)->sizeMe)(twindow);
- }
- }
-
- case mouseUp:
- /* don't care */
- break;
-
- /* same action for key or auto key */
-
- case keyDown:
- case autoKey:
- if (myEventRecord.modifiers & cmdKey) {
- AdjustMenus();
- DoSelected(MenuKey(myEventRecord.message & charCodeMask));
- }
- break;
-
- case keyUp:
- /* don't care */
- break;
-
- case diskEvt:
- /* I don't do anything special for disk events, this just passes them */
- /* to a function that checks for an error on the mount */
- DoDiskEvents(myEventRecord.message);
- break;
-
- case activateEvt:
- if (IsMyWindow((WindowPtr)myEventRecord.message)) {
- tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message);
- ((*tempWCH)->activateMe)((WindowPtr)myEventRecord.message,(myEventRecord.modifiers & activeFlag));
- }
- break;
-
- case networkEvt:
- /* don't care */
- break;
-
- case driverEvt:
- /* don't care */
- break;
-
- case app4Evt:
- switch ((myEventRecord.message >> 24) & 0x0FF) { /* high byte of message */
- case suspendResumeMessage: /* suspend/resume is also an activate/deactivate */
- gInBackground = (myEventRecord.message & kResumeMask) == 0;
- if(gInBackground)
- gMySleep = kBackSleep;
- else
- gMySleep = kFrontSleep;
- break;
- }
- break;
-
-
- /* This dispatches high level events (AppleEvents, for example) */
- /* to our dispatch routine. This is NEW in the event loop for */
- /* System 7 */
-
- case kHighLevelEvent:
- DoHighLevel(&myEventRecord);
- break;
-
- default:
- break;
-
-
- }
- }
- while (gQuit != true);
-
- }
-
- /* DoDaCall opens the requested DA. It's here as a seperate routine if you'd */
- /* like to perform some action or just know when a DA is opened in your */
- /* layer. Can be handy to track memory problems when a DA is opened */
- /* with an Option-open */
- void DoDaCall(MenuHandle themenu, long theit)
- {
- long qq;
- char DAname[255];
- GetItem(themenu, theit, &DAname);
- qq = OpenDeskAcc(DAname);
- }
-
- /* end DoDaCall */
-
- /* DoDiskEvents just checks the error code from the disk mount, */
- /* and puts up the 'Format' dialog (through DIBadMount) if need be */
- /* You can do much more here if you care about what disks are */
- /* in the drive */
- void DoDiskEvents(long dinfo) /* hi word is error code, lo word is drive number */
- {
- short hival, tommy;
- Point fredpoint = {
- 40, 40
- };
- hival = HiWord(dinfo);
- if (hival != noErr) /* something happened */ {
- tommy = DIBadMount(fredpoint, dinfo);
- }
- }
-
- /* draws my window. */
- void DrawMain(WindowPtr drawIt)
- {
- Str32 theWords;
- RgnHandle tempRgn;
- short cellWide;
- windowCHandle tempWCH;
- Rect scratchRect;
- register qq;
- BeginUpdate(drawIt);
- SetPort(drawIt);
- /* get our extra data */
- tempWCH = (windowCHandle)GetWRefCon(drawIt);
-
- /* update the list in this window */
- LUpdate(drawIt->visRgn, (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
-
- /* now draw some lines between the cells for neatness */
-
- cellWide = (*(*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList)->cellSize.h;
-
- /* draw my header information Please */
- for (qq = 1; qq < 5; qq++) {
- GetIndString(theWords, kGeneralStrings, qq);
- MoveTo(cellWide * (qq - 1) + kIndent, kIndentDown);
- DrawString(theWords);
- }
-
- /* seperate routine to draw the grid lines, since I also call this from elsewhere */
- ReDrawGridLines(drawIt, (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
-
- /* clip to the area the grow box is in, and draw it */
- scratchRect = drawIt->portRect;
- scratchRect.top = scratchRect.bottom - kScrollBarFudge;
- scratchRect.left = scratchRect.right - kScrollBarFudge;
- tempRgn = NewRgn();
- GetClip(tempRgn);
- ClipRect(&scratchRect);
- DrawGrowIcon(drawIt);
- SetClip(tempRgn);
- DisposeRgn(tempRgn);
-
- EndUpdate(drawIt);
- }
-
- /* my menu action taker. It returns a Boolean which I usually ignore, but it */
- /* mught be handy someday */
- /* I usually use it in an application to determine if a keystroke was accepted */
- /* by a menu or whether it should be passed along to any other key acceptors */
- Boolean DoSelected(long val)
- {
- short loval, hival;
- Boolean returnVal = false;
- loval = LoWord(val);
- hival = HiWord(val);
-
- switch (hival) { /* switch off the menu number selected */
- case kAppleMenu: /* Apple menu */
- if (loval != kAboutItem) { /* if this was not About, it's a DA */
- DoDaCall(GetMHandle(kAppleMenu), loval);
- } else {
- Alert(kAboutBox, nil); /* do about box */
- }
- returnVal = true;
- break;
- case kFileMenu: /* File menu */
- switch (loval) {
- case kNewItem:
- AddNewWindow(kDocWindowResID);
- break;
- case kCloseItem:
- CloseTheWindow(FrontWindow());
- break;
- break;
- case kQuitItem:
- gQuit = true; /* only item */
- returnVal = true;
- break;
- default:
- break;
- }
- break;
-
- case kEditMenu:
- /* edit menu junk */
- /* don't care */
- switch (loval) {
- default:
- break;
- }
- break;
- case kToolsMenu:
- /* add all your test stuff here */
- switch (loval) {
- case kGetResInfoItem:
- GetAResourceType(FrontWindow());
-
- break;
- default:
- break;
- }
- break;
-
- case kHMHelpMenuID: /* Defined in Balloons.h */
- /* I only care about this item. If anything else is returned here, I don't know what */
- /* it is, so I leave it alone. Remember, the Help Manager chapter says that */
- /* Apple reserves the right to add and change things in the Help menu */
- if (loval == gHelpItem)
- SampleHelpDialog();
- break;
-
- }
- /* dim the hilit menu title */
- HiliteMenu(0);
- return(returnVal);
- }
-
- /* handles clicks in my windows */
- void DoDocumentClick(WindowPtr theWindow)
- {
- windowCHandle tempWCH = (windowCHandle)GetWRefCon(theWindow);
- Point thePoint;
- GetMouse(&thePoint);
- /* since the only clickable thing that will get to here is the List, pass */
- /* off to the list manager */
- /* I'm passing nil for the modifiers, since selections and ranges don't */
- /* really mean anything in this sample */
- LClick(thePoint, nil, (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
-
- /* if they clicked, then the grid lines may have to be updated */
- /* since they could have scrolled the list. I could check for that, but */
- /* it doesn't cause any problems just to redraw */
- ReDrawGridLines(theWindow, (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
- }
-
- /* I'm not doing error handling in this sample for clarities sake, you should. Hah, */
- /* easy for me to say, huh? */
- void DoHighLevel(EventRecord *AERecord)
- {
- /* this passes off to my AppleEvent handlers automatically. */
- /* If I don't have a handler for this event, then this function */
- /* returns an error */
- AEProcessAppleEvent(AERecord);
-
- }
-
- /* end DoHighLevel */
-
- /* This is the standard Open Application event. */
- pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- {
- WindowPtr myWindow;
-
- #pragma unused (messagein,reply,refIn)
- /* we of course don't do anything here in this simple app */
- /* except open our window */
- myWindow = AddNewWindow(kDocWindowResID);
-
- return(noErr);
- }
-
- /* end AEOpenHandler */
-
- /* Open Doc, opens our documents. Remember, this can happen at application start AND */
- /* anytime else. If your app is up and running and the user goes to the desktop, hilites one */
- /* of your files, and double-clicks or selects Open from the finder File menu this event */
- /* handler will get called. Which means you don't do any initialization of globals here, or */
- /* anything else except open then doc. */
- /* SO-- Do NOT assume that you are at app start time in this */
- /* routine, or bad things will surely happen to you. */
-
- pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- {
- #pragma unused (messagein,refIn,reply)
- /* we of course don't do anything here */
- /* since I don't have any documents */
- return(errAEEventNotHandled); /* we have no docs, so no odoc events should come to us */
- }
-
- pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- { /* no printing handler in yet, so we'll ignore this */
- /* the operation is functionally identical to the ODOC event, with the additon */
- /* of calling your print routine. */
- #pragma unused (messagein,refIn,reply)
- /* we of course don't do anything here */
- return(errAEEventNotHandled); /* we have no docs, so no pdoc events should come to us */
- }
-
- /* Standard Quit event handler, to handle a Quit event from the Finder, for example. */
- /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life. */
- /* OK, it's a few months after I wrote that comment, and I've seen a lot of code */
- /* come through DTS that calls ExitToShell from quit handlers. Let me explain... */
- /* When an AppleEvent Handler is called (like this quit handler) you are ALMOST */
- /* 100% in your application world. A5 is right, you can call any toolbox function, */
- /* you can call your own routines, everything _seems_ like you are in complete */
- /* control. Well, almost but not quite. The routine has been dispatch to from the */
- /* AppleEvent Manager's space, so you _must_ return to that at some point! */
- /* Which is why you can't call ETS from here. When you call ExitToShell from an */
- /* AE Handler, the most likely thing that happens is the FInder quits, and your */
- /* application keeps running. Which ain't what you want, y'know? */
- /* so, DON'T CALL EXITTOSHELL FROM AN APPLEEVENT HANDLER!!!!!!!!!!!!!! */
- pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- {
- #pragma unused (messagein,refIn,reply)
- gQuit = true;
- return(noErr);
- }
-
- /* This is my sample help dialog. Does not do anything, expand as you need */
- void SampleHelpDialog(void)
- {
- DialogPtr tdial = GetNewDialog(kSampHelp, nil, (WindowPtr)-1);
- short itemhit = 0;
- gExtraDialogFilter = nil; /* no extras this time */
- while (itemhit != ok) {
-
- ModalDialog((ModalFilterProcPtr)standardDialogFilter, &itemhit);
- }
- DisposDialog(tdial);
- }
-
-
- #pragma segment Initialize
- void InitalizeApp(void)
- {
- Handle myMenu;
- MenuHandle helpHandle, appleMenuHandle;
- StringHandle helpString;
- short count;
- long vers;
- /* move my applLimit to the end of the space I can grow to */
- MaxApplZone();
-
- /* Init the Managers */
- InitGraf((Ptr)&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
- /* Check system version */
- Gestalt(gestaltSystemVersion, &vers);
- vers = (vers >> 8) & 0xf; /* shift result over and mask out major version number */
- if (vers < 7) {
- StopAlert(kBadSystem, nil);
- ExitToShell();
- }
-
- /* Init and install my AppleEvent handlers */
- InitAEStuff();
-
- /* set up my menu junk */
- myMenu = GetNewMBar(kMBarID);
- SetMenuBar(myMenu);
- appleMenuHandle = GetMHandle(kAppleMenu);
- AddResMenu(appleMenuHandle, 'DRVR');
-
- /* now install my Help menu item in the Help Manager's menu */
- HMGetHelpMenuHandle(&helpHandle); /* Get the Hlpe menu handle */
- count = CountMItems(helpHandle); /* How many items are there? */
- helpString = GetString(kHelpString); /* get my help string */
- HLock((Handle)helpString);
- InsMenuItem(helpHandle, (Ptr)*helpString, count + 1); /* insert my item in the Help menu */
- ReleaseResource((Handle)kHelpString);
- gHelpItem = CountMItems(helpHandle); /* The number of the item */
-
- DrawMenuBar();
- GetCurrentProcess(&gOurSN); /* Get our process serial number for later use, if needed */
-
- }
-
- /* InitAEStuff installs my appleevent handlers */
- void InitAEStuff(void)
- {
- AEinstalls HandlersToInstall[] = { {
- kCoreEventClass, kAEOpenApplication, AEOpenHandler
- }, {
- kCoreEventClass, kAEOpenDocuments, AEOpenDocHandler
- }, {
- kCoreEventClass, kAEQuitApplication, AEQuitHandler
- }, {
- kCoreEventClass, kAEPrintDocuments, AEPrintHandler
- },
- /* The above are the four required AppleEvents. */ {
- kCoreEventClass, kAEAnswer, AEAnswerHandler
- }
- };
-
- OSErr aevtErr = noErr;
- long aLong = 0;
- Boolean gHasAppleEvents = false;
- /* Check this machine for AppleEvents. If they are not here (ie not 7.0)
- * then we exit */
- gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
- /* The following series of calls installs all our AppleEvent Handlers.
- * These handlers are added to the application event handler list that
- * the AppleEvent manager maintains. So, whenever an AppleEvent happens
- * and we call AEProcessEvent, the AppleEvent manager will check our
- * list of handlers and dispatch to it if there is one.
- */
- if (gHasAppleEvents) {
- register qq;
- for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) {
- aevtErr = AEInstallEventHandler(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent,
- HandlersToInstall[qq].theProc, 0, false);
- if (aevtErr) {
- ExitToShell(); /* just fail, baby */
- }
- }
- } else {
- ExitToShell();
- }
- }
-
- /* end InitAEStuff */
-
-
- #pragma segment Main
- /* adds a new window to my environment */
-
- WindowPtr AddNewWindow(short theID)
- {
- /* the following rects and cell are for list creation */
- Rect viewRect;
-
- Rect dataBRect = { /* three columns */
- 0, 0, 0, 4
- };
- Cell cSize = {
- 0, 0
- }; /* default cell size */
-
- windowCHandle setControls;
- WindowPtr tempWP;
- short cnt = 0;
- /* get a new window */
- tempWP = GetNewWindow(theID, 0, (WindowPtr)-1);
-
- /* mark it as my document window */
- ((WindowPeek)tempWP)->windowKind = kMyDocumentWindow;
-
- /* add our control structure to it */
- setControls = (windowCHandle)NewHandleClear(sizeof(windowControl));
-
- /* stop stuffing refCon directly <ckh 1.0.3> */
- SetWRefCon(tempWP, (long)setControls);
-
- /* add a unique ID */
- AddWindowID(tempWP);
-
- HLock((Handle)setControls); /* lock it down while we fill it*/
-
- /* add pointers to our procedures for drawing, saving, and closing */
- /* This way, all I need is one dispatch point for drawing, closing */
- /* or whatever, I don't have to case off the window kind to go to the */
- /* correct routine. Kinda like object-oriented programming, but I won't */
- /* admit that. */
-
- (*setControls)->drawMe = DrawMain;
- (*setControls)->clickMe = DoDocumentClick;
- (*setControls)->sizeMe = SizeMain;
- (*setControls)->closeMe = CloseTheWindow;
- (*setControls)->activateMe = ActivateMain;
-
- /* in this sample, this handle will simply contain a list */
- /* to display in the window */
- (*setControls)->generalData = NewHandle(sizeof(documentExtraData));
-
- /* I'nm going to store my ListHandle in generalData */
- HLock((*setControls)->generalData);
- viewRect = tempWP->portRect;
- viewRect.top += kTopLineHeight; /* room for some text at the top */
- viewRect.bottom -= kScrollBarFudge; /* romm for list scroll bars */
- viewRect.right -= kScrollBarFudge;
-
- (*(documentExtraDataHdl)((*setControls)->generalData))->displayList = LNew(&viewRect, &dataBRect, cSize, nil, tempWP, true,
- false, true, true);
-
- LActivate(true, (*(documentExtraDataHdl)((*setControls)->generalData))->displayList);
- LDoDraw(true, (*(documentExtraDataHdl)((*setControls)->generalData))->displayList);
-
- HUnlock((*setControls)->generalData);
- HUnlock((Handle)setControls);
-
- return(tempWP);
- }
-
- /* handle a resize, which means resizing the list in this example */
- void SizeMain(WindowPtr theWindow)
- {
- WindowPtr tempWP;
- windowCHandle tempWCH = (windowCHandle)GetWRefCon(theWindow);
-
- GetPort(&tempWP);
- InvalRect(&theWindow->portRect);
-
- /* change the list size to the new size for the winder */
- /* make sure to leave border space for the scroll bars */
- LSize((theWindow->portRect.right - theWindow->portRect.left) - kScrollBarFudge,
- ((theWindow->portRect.bottom - theWindow->portRect.top) - kScrollBarFudge) - kTopLineHeight,
- (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
- SetPort(tempWP);
- }
-
- /* see if the window in question is really mine */
- Boolean IsMyWindow(WindowPtr theWind)
- {
- return(((WindowPeek)theWind)->windowKind == kMyDocumentWindow);
- }
-
-
- /* Here I'm looking for MungeDeamon. */
- /* First I look to see if the process is already running. */
- /* If it's not, I use PBCatSearch to find it, and launch it */
- /* if I find it */
- OSErr FindOrLaunchAProcess(OSType theSig, AEDesc *theAddress)
- {
- OSErr myError;
-
- /* let people know I'm busy looking */
- DialogPtr search = GetNewDialog(kSearchDialog, nil, (WindowPtr)-1);
-
- /* param block for cat search */
- CSParamPtr csBlockPtr = NewPtrClear(sizeof(CSParam));
-
- LaunchParamBlockRec launchThis;
- long dirIDUnused;
- Str32 nulString = "\p";
-
- DrawDialog(search);
- /* first just see if it's already running */
- if (noErr == FindAProcess(theSig, &launchThis.launchProcessSN)) {
- /* it was running */
- /* make an address desc from this PSN */
- myError = AECreateDesc(typeProcessSerialNumber, (Ptr)&launchThis.launchProcessSN, sizeof(ProcessSerialNumber),
- theAddress);
-
- } else {
- /* we couldn't find it in the process list, look for it on the volume and */
- /* launch it if found */
- /* initialize the parameter block */
-
- /* • NOTE: I'm just searching the default volume here! */
- /* you might want to search all the volumes. */
- if (csBlockPtr) {
- csBlockPtr->ioSearchInfo1 = (CInfoPBPtr)NewPtrClear(sizeof(CInfoPBRec));
- csBlockPtr->ioSearchInfo2 = (CInfoPBPtr)NewPtrClear(sizeof(CInfoPBRec));
- if (csBlockPtr->ioSearchInfo1 && csBlockPtr->ioSearchInfo2) {
-
- /* only looking for 1 */
- csBlockPtr->ioMatchPtr = (FSSpecPtr)NewPtrClear(sizeof(FSSpec) * 1);
-
- if (csBlockPtr->ioMatchPtr) {
- /* Now see if we can create an optimization buffer */
- csBlockPtr->ioOptBuffer = NewPtr(2048);
- if (csBlockPtr->ioOptBuffer)
- csBlockPtr->ioOptBufSize = 2048;
- else
- csBlockPtr->ioOptBufSize = 0; /* no buffer, sorry */
- csBlockPtr->ioReqMatchCount = 1;
- csBlockPtr->ioSearchTime = 0; /* no timeout */
- }
- }
- }
-
- HGetVol(nil, &csBlockPtr->ioVRefNum, &dirIDUnused); /* get default volume for search */
-
- csBlockPtr->ioSearchInfo1->hFileInfo.ioNamePtr = nil;
- csBlockPtr->ioSearchInfo2->hFileInfo.ioNamePtr = nil;
- csBlockPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdCreator = theSig;
- csBlockPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdType = 'APPL';
- csBlockPtr->ioSearchBits = fsSBFlFndrInfo;
- csBlockPtr->ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdCreator = 0xFFFFFFFF;
- csBlockPtr->ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdType = 0xFFFFFFFF;
-
- myError = PBCatSearch(csBlockPtr, false); /* search sync */
-
- if (myError == noErr && csBlockPtr->ioActMatchCount != 0) {
- /* we found it, so launch it */
- launchThis.reserved1 = nil;
- launchThis.reserved2 = nil;
- launchThis.launchPreferredSize = nil;
- launchThis.launchMinimumSize = nil;
- launchThis.launchAvailableSize = nil;
- launchThis.launchAppParameters = nil;
- launchThis.launchBlockID = extendedBlock;
- launchThis.launchEPBLength = extendedBlockLen;
- launchThis.launchFileFlags = nil;
- launchThis.launchControlFlags = launchContinue + launchNoFileFlags + launchDontSwitch;
- launchThis.launchAppSpec = &csBlockPtr->ioMatchPtr[0];
- myError = LaunchApplication(&launchThis);
- if (myError == noErr) {
- /* it launched fine. we can use the PSN to make a target */
- AECreateDesc(typeProcessSerialNumber, (Ptr)&launchThis.launchProcessSN, sizeof(ProcessSerialNumber), theAddress);
-
- }
- }
-
- /* no matter what happened, kill the memory we had allocated */
- if (csBlockPtr) {
- if (csBlockPtr->ioSearchInfo1)
- DisposPtr((Ptr)csBlockPtr->ioSearchInfo1);
- if (csBlockPtr->ioSearchInfo2)
- DisposPtr((Ptr)csBlockPtr->ioSearchInfo2);
- if (csBlockPtr->ioMatchPtr)
- DisposPtr((Ptr)csBlockPtr->ioMatchPtr);
- if (csBlockPtr->ioOptBuffer)
- DisposPtr((Ptr)csBlockPtr->ioOptBuffer);
- DisposPtr((Ptr)csBlockPtr);
- }
- } /* catsearch section end */
- DisposDialog(search);
- return(myError);
- }
-
- /* a litte routine to walk the process list looking for a specific application */
- /* signature */
- OSErr FindAProcess(OSType creatorToFind, ProcessSerialNumberPtr processSN)
- {
- ProcessInfoRec infoRecToFill;
- FSSpec tempSpec;
- Str255 tempName;
- OSErr myErr = noErr;
- processSN->lowLongOfPSN = kNoProcess;
- processSN->highLongOfPSN = kNoProcess;
- infoRecToFill.processName = &tempName;
- infoRecToFill.processAppSpec = &tempSpec;
- do {
- /* start at the beginning of the list, walk through all the processes */
- /* until we find it or error out at the end of the list */
- myErr = GetNextProcess(processSN);
- if (myErr == noErr)
- GetProcessInformation(processSN, &infoRecToFill);
- if (infoRecToFill.processSignature == creatorToFind)
- break;
- }
- while (myErr == noErr);
-
- return(myErr);
- }
-
- /* This is an AppleEvent Idle function. It can be passed to AEInteractWithUser */
- /* or AESend. */
- /* What it does is this; */
- /* If some AppleEvent thing is taking a really long time, the AppleEvent manager */
- /* will call WaitNextEvent FOR you (yeah, yeah, only one event loop per app, oh well) */
- /* and give you a result (limited) if you need to do something. That something */
- /* will only be an update,activate,OSevent, or null event */
- pascal Boolean CommonIdleFunction(EventRecord *whatEvent, long *sleeping, RgnHandle *mouseRgn)
- {
- #pragma unused (sleeping,mouseRgn)
- extern Boolean gInBackground;
-
- extern RgnHandle mousergn;
- switch (whatEvent->what) {
- case updateEvt:
- if (IsMyWindow((WindowPtr)whatEvent->message)) {
- windowCHandle tempWCH = (windowCHandle)GetWRefCon((WindowPtr)whatEvent->message);
- (ProcPtr)((*tempWCH)->drawMe)((WindowPtr)whatEvent->message);
- }
- break;
- case activateEvt:
-
- break;
- case app4Evt: /* or kOSEvent, I'm old fashioned */
- switch ((whatEvent->message >> 24) & 0x0FF) { /* high byte of message */
- case suspendResumeMessage: /* suspend/resume is also an activate/deactivate */
- gInBackground = (whatEvent->message & kResumeMask) == 0;
-
- break;
- }
- break;
- case nullEvent:
- break;
-
- }
- return(false); /* If it takes for-ever I will wait, for you... Sorry. */
- }
-
- /* GetAResourceType asks for the resource type to get info on */
- void GetAResourceType(WindowPtr theWindow)
- {
- Rect tempRect;
- short tempItem;
- Handle tempHandle;
- Str15 myStr;
- ResType theType;
- short hitItem;
-
- DialogPtr myDialog = GetNewDialog(kResTypeDialog, nil, (WindowPtr)-1);
-
- /* New System 7 dialog manager calls, see tech note #304 */
- /* interface to these calls is in OtherResInfo.protos.h */
- SetDialogDefaultItem(myDialog, ok);
- SetDialogCancelItem(myDialog, cancel);
- SetDialogTracksCursor(myDialog, true);
-
- do {
- /* since I'm doing some restriction, I have to add an additional filtering */
- /* step, see the standardDialogFilter for how this is used */
- gExtraDialogFilter = filterIt;
-
- ModalDialog((ModalFilterProcPtr)standardDialogFilter, &hitItem);
- if (hitItem == kResTypeQuitCheck)
- SetCtlValue(SnatchHandle(myDialog, hitItem), (GetCtlValue(SnatchHandle(myDialog, hitItem)) ? 0 : 1));
- }
- while (hitItem != ok && hitItem != cancel);
-
- if (hitItem == ok) {
-
- /* get the type and hammer it */
- GetDItem(myDialog, kResTypeEditLine, &tempItem, &tempHandle, &tempRect);
- GetIText(tempHandle, myStr);
-
- /* make sure there are 4 characters here, please */
- if (myStr[0] == 4) {
- Boolean theQuitter;
- BlockMove((Ptr)&myStr[1], (Ptr)&theType, sizeof(theType));
-
- /* also get the quit value */
- theQuitter = GetCtlValue(SnatchHandle(myDialog, kResTypeQuitCheck));
- DisposDialog(myDialog);
- /* Send this info off to my event sender, please */
-
- SendInfoEvent(theType, theQuitter, theWindow);
- }
- } else {
- DisposDialog(myDialog);
-
- }
- }
-
-
- /* Some dialog filtering things */
- /* TabRetEsc toggles the cancel or OK button for keystrokes, and */
- /* treats a Tab press as selecting the whole edit line contents */
-
- Boolean TabRetEsc(DialogPtr inputDialog, EventRecord *myDialogEvent, short *theDialogItem)
- {
- Boolean returnValue = false;
- long tilticks;
- WindowPtr tempWindowPtr;
- char theKey = myDialogEvent->message &charCodeMask;
- GetPort(&tempWindowPtr);
- SetPort(inputDialog);
- switch (theKey) {
- case kReturnKey:
- case kEnterKey: /* enter key */
- /* This filters for Return or Enter as item 1, and Esc as item 2 */
- *theDialogItem = ok; /* change whatever the current item is to the OK item */
- /* now we need to invert the button */
- HiliteControl(SnatchHandle(inputDialog, ok), inButton);
- Delay(8, &tilticks); /* wait about 8 ticks so they can see it */
- HiliteControl(SnatchHandle(inputDialog, ok), false);
- returnValue = true;
- break;
- /* This filters the escape key as the same as item 2 (the canx button, usually ) */
- case kEscKey:
- *theDialogItem = cancel;
- HiliteControl(SnatchHandle(inputDialog, cancel), inButton);
- Delay(8, &tilticks); /* wait about 8 ticks so they can see it */
- HiliteControl(SnatchHandle(inputDialog, cancel), false);
- returnValue = true;
- break;
- case kTabKey:
- /* I'm filtering the tab key here so a tab selects all the */
- /* text in the edit line, as a convinience */
- SelIText(inputDialog, kResTypeEditLine, 0, 5);
- returnValue = true; /* don't allow edit line swaps */
- break;
- }
- SetPort(tempWindowPtr);
-
- return(returnValue);
-
- }
-
- /* Main dialog filter */
- pascal Boolean filterIt(DialogPtr inputDialog, EventRecord *myDialogEvent, short *theDialogItem)
- {
-
- Boolean returnVal = false;
- ModalFilterProcPtr theModalProc;
- char theKey;
- Rect tempRect;
- short tempItem;
- Handle tempHandle;
- char tempKey;
- Str255 myStr;
- long offset;
- short selection;
- long scrapLen;
- short resultLen;
- Boolean wasAKey = false;
- if (myDialogEvent->what == updateEvt && myDialogEvent->message != inputDialog) {
- /* May be a pending update event for another window, handle it so */
- /* other layers get time */
- windowCHandle tempWCH;
- WindowPtr theWindow = (WindowPtr)myDialogEvent->message;
- /* draw my window if it's really mine */
- if (((WindowPeek)theWindow)->windowKind == kMyDocumentWindow) {
- tempWCH = (windowCHandle)GetWRefCon(theWindow);
- (ProcPtr)((*tempWCH)->drawMe)((WindowPtr)theWindow);
-
- *theDialogItem = 0;
- returnVal = true;
- }
- } else {
- wasAKey = (myDialogEvent->what == keyDown) || (myDialogEvent->what == autoKey);
-
- if ((wasAKey)) {
- /* first check on the Big Three, tab, return, and escape */
- if (!(returnVal = TabRetEsc(inputDialog, myDialogEvent, theDialogItem))) {
-
- /* not one of those, see if this keystroke will fit */
- /* in the edit line (restricted to 4 characters for a ResType) */
- /* Here I'm seeing if anything is selected, and getting the length */
- /* of the desk scrap in case the user presses */
- /* Copy or Paste keys */
-
- selection = HasSelectionRange((DialogPeek)inputDialog);
- scrapLen = GetScrap(nil, 'TEXT', &offset);
-
- GetDItem(inputDialog, kResTypeEditLine, &tempItem, &tempHandle, &tempRect);
- GetIText(tempHandle, myStr);
-
- /* calculate the result of adding the scrap to the current record.We use */
- /* this in a few places here */
- resultLen = myStr[0] + (scrapLen - selection);
-
- theKey = myDialogEvent->message & charCodeMask;
- tempKey = theKey;
- if (tempKey >= 0x61 && tempKey <= 0x7a)
- tempKey -= 0x20;
-
- if (myStr[0] > 3) { /* over 4, see what it is */
-
- if (IsEditKey(theKey, myDialogEvent->modifiers)) {
- /* it was an editing key, but it MAY be a command-V. */
- /* If it's a command-V then we won't allow it UNLESS */
- /* there is a slection range AND the new data won't overrun things */
- if ((tempKey == 'V') && (myDialogEvent->modifiers & cmdKey)) {
-
- /* this was a paste.check selection range and scrap len*/
- if (resultLen < 4) {
- returnVal = false; /* net result is4 or less */
- } else {
- SysBeep(1);
- returnVal = true;
- }
- } else {
- returnVal = false; /* don't filter out editing keys */
- }
- } else {
- /* One more check (this can get complicated, huh?) */
- /* We now look to see if there is a selection range.If there */
- /* is a range of 1 or more characters, then the one character they are entering */
- /* now will replace that, and we'll end up with _less_ than 4 (or equal) */
- /* to do this, we have to get the TERecord out of the dialog.*/
- /* I'm going to do this in a seperate function */
- if (selection == nil) {
- SysBeep(1); /* complain a little */
- returnVal = true; /* tell the dialog manager that we handled this already and */
- /* it doesn't have to, so the keystroke will _not_ get */
- /* added to the edit line */
- }
- }
- } else {
- /* even if we're less than 4 currently, a Command-V (paste) could put us over */
- /* so check it out */
-
- if ((tempKey == 'V') && (myDialogEvent->modifiers & cmdKey)) {
-
- /* Gettting the scrap with a nil handle, which does not give us data, just */
- /* returns the size */
- if (resultLen > 3) {
- SysBeep(1); /* complain a little */
- returnVal = true; /* tell the dialog manager that we handled this already and */
-
- }
- }
- }
- }
- }
- }
- if (!returnVal) {
-
- OSErr myErr = GetStdFilterProc(&theModalProc);
- if (myErr == noErr)
- returnVal = theModalProc(inputDialog, myDialogEvent, theDialogItem);
- }
- return(returnVal);
- }
-
- /* a little routine to see if there is text selected in the edit line, I need */
- /* this to determine if a new keystroke will fit. */
- /* An example; */
- /* If I'm restricting to 4 characters, and there are already 4 characters in the */
- /* edit line, a simple check would refuse any more keystrokes. */
- /* BUT, if there is a selection range, the new keystroke is actually */
- /* going to replace some of the characters, so it should in fact be accepted */
-
- short HasSelectionRange(DialogPeek inputDialog)
- {
- TEHandle theTERecord = inputDialog->textH;
- short returnVal = (*theTERecord)->selEnd -(*theTERecord)->selStart;
-
- return(returnVal);
- }
-
- /* end HasSelectionRange */
-
- /* a little utility to see if the current key is an edit-type key */
- Boolean IsEditKey(char theKey, short modifiers)
- {
- register qq;
- Boolean returnVal = false;
- char editChars[] = {
- kLeftArrow, kUpArrow, kRightArrow, kDownArrow, kBackSpace, kEscKey
- };
- char commandEdits[] = {
- 'C', 'V', 'P'
- };
- for (qq = 0; qq < sizeof(editChars) / sizeof(char); qq++) {
- if (theKey == editChars[qq])
- returnVal = true;
- }
- if (returnVal != true && (modifiers & cmdKey)) {
- /* check for XCP */
- /* Do you want me to use 'toupper()'?What! And link in all of StdLib! aggggg */
- if (theKey >= 0x61 && theKey <= 0x7a)
- theKey -= 0x20;
- for (qq = 0; qq < sizeof(commandEdits) / sizeof(char); qq++) {
- if (theKey == commandEdits[qq])
- returnVal = true;
- }
- }
- return(returnVal);
- }
-
- /* end IsEditKey */
-
- /* Gets the ControlHandle for the item you want in the dialog box thebox.*/
- /* Handy for setting checkboxes and radio buttons */
- ControlHandle SnatchHandle(DialogPtr thebox, short theGetItem)
- {
- short itemtype;
- Rect itemrect;
- Handle thandle;
-
- GetDItem(thebox, theGetItem, &itemtype, &thandle, &itemrect);
- return((ControlHandle)thandle);
- }
-
- /* end SnatchHandle */
-
- /* SendInfoEvent is where we find and send an event to our backgrounder. */
- /* We are specifing kAEQueueReply, so we will not get a reply at this time */
- /* it will come to us through our regular event loop */
- void SendInfoEvent(ResType theType, Boolean quit, WindowPtr theWindow)
- {
- StandardFileReply theReply;
- OSErr myErr = noErr;
- Point myPoint = {
- -1, -1
- };
- AliasHandle theAlias;
- windowCHandle tempWCH = (windowCHandle)GetWRefCon(theWindow);
-
- AppleEvent theEvent;
- AEDesc tempDesc;
- AEDesc theAddress;
- SFTypeList myList = {
- 'APPL'
- };
- /* I'm using custom get file ONLY because I want to have a different */
- /* dialog arrangement */
- /* I'm not doing anything else with the thing */
- CustomGetFile(nil, 1, &myList, &theReply, 4000, myPoint, nil, nil, nil, nil, nil);
-
- if (theReply.sfGood) {
-
- /* I'm changing the name of the window to reflect this file name now, just for grins */
- SetWTitle(theWindow, &theReply.sfFile.name);
-
- myErr = NewAlias(nil, &theReply.sfFile, &theAlias);
-
- if (myErr == noErr) {
-
- /* make an event and send to our friend */
- myErr = FindOrLaunchAProcess(kMungeDeamonCreator, &theAddress);
-
- if (myErr == noErr) {
-
- myErr = AECreateAppleEvent(kMyEventClass, kGetResEvent, &theAddress, kAutoGenerateReturnID, (*tempWCH)->windowID,
- &theEvent);
- if (myErr == noErr) {
- /* make a desc for the alias, and add it to the event */
-
- HLock((Handle)theAlias);
- myErr = AECreateDesc(typeAlias, (Ptr)*theAlias, GetHandleSize((Handle)theAlias), &tempDesc);
- if (myErr == noErr) {
-
- myErr = AEPutKeyDesc(&theEvent, keyDirectObject, &tempDesc);
-
- /* now add a desc for the resType */
- AEPutParamPtr(&theEvent, kMyResTypeParam, typeMyResType, (Ptr)&theType, sizeof(theType));
-
- /* here's where you'd add the quit code if you want to */
- if (quit) {
- AEPutKeyPtr(&theEvent, keyMyQuitFlag, typeBoolean, (Ptr)&quit, sizeof(quit));
- }
-
- if (myErr == noErr) {
-
- /* do the actual sending */
- myErr = AESend(&theEvent, nil, kAENeverInteract + kAEQueueReply, kAENormalPriority, kAEDefaultTimeout,
- nil, (EventFilterProcPtr)CommonIdleFunction);
-
- AEDisposeDesc(&theEvent);
-
- }
- }
- AEDisposeDesc(&tempDesc);
-
- }
- } else {
- /* couldn't launch the process for some reason or 'nother */
- StopAlert(kCouldntFindProc, nil);
- }
- }
- DisposHandle((Handle)theAlias);
-
- }
- }
-
- /* AEAnswerHandler */
- /* Since I'm sending my event with kAEQueueReply, that means that my reply will */
- /* come into my event loop as a standard appleevent of type kAEAnswer */
- /* this is my handler for those types of events */
- pascal OSErr AEAnswerHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- {
- #pragma unused (reply,refIn)
- /* yank my information, and put it in my list */
- OSErr myErr;
- WindowPtr theWindow;
- myResInfoPtr nowInfo = NewPtrClear(sizeof(myResInfoStruct));
- OSErr listErr = noErr;
- WindowPtr tempWP;
- unsigned long theLong;
- AEDesc theList;
- Cell cSize = {
- 0, 0
- };
- Size sizeBack;
- long longErr = nil;
- DescType typeBack;
- /* get our transaction ID, which matches the window ID */
- /* First thing we look for is an error */
- myErr = AEGetParamPtr(messagein, keyErrorNumber, typeLongInteger, &typeBack, (Ptr)&longErr, sizeof(long), &sizeBack);
- if (myErr == noErr) {
- /* if there was no error, that means that an error was returned */
- /* kind of backwards, but what that means is.... */
- /* A error from the other process comes back to me as a parameter in the */
- /* event. If I CAN pull that parameter (i.e. noErr result from above ) that */
- /* means that an error exists. */
- /* If I CAN'T pull the error descriptor, that means that I do not have an error */
- SayError(longErr);
- }
-
- /* if there was noErr, or if the event just overflowed, then there is still much information */
- /* to display, so we'll display it */
- if (longErr == noErr || longErr == kAppleEventTooBig) {
- /* save the current port */
- GetPort(&tempWP);
-
- /* get the transaction ID, which equates to our unique window ID */
- AEGetAttributePtr(messagein, keyTransactionIDAttr, typeLongInteger, &typeBack, (Ptr)&theLong, sizeof(long), &sizeBack);
-
- /* find that window */
- theWindow = FindWindowByID(theLong);
-
- if (theWindow) {
- windowCHandle tempWCH = (windowCHandle)GetWRefCon(theWindow);
- SetPort(theWindow);
- /* get rid of all current contents */
- LDelRow(0, 0, (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
-
- /* turn off drawing whilst adding */
- LDoDraw(false, (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
-
- /* get the direct object, which is my list */
- myErr = AEGetKeyDesc(messagein, keyDirectObject, typeAEList, &theList);
- if (myErr == noErr) {
- /* we got us a list of stuff, start pulling and adding it to our window */
- long listCount;
- long currentIndex;
- AECountItems(&theList, &listCount);
-
- /* index through all the things I got back, and add them to the list */
- /* list is 1, not 0, based */
- for (currentIndex = 1; currentIndex <= listCount; currentIndex++) {
-
- Str15 theNumberString;
- AEGetNthPtr(&theList, currentIndex, typeMyResInfoType, nil, &typeBack, (Ptr)nowInfo, sizeof(myResInfoStruct),
- &sizeBack);
-
- /* add this info to my list */
-
- LAddRow(1, cSize.v, (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList); /* a new item, add a row for it */
-
- NumToString(nowInfo->id, theNumberString);
- LAddToCell(&theNumberString[1], theNumberString[0], cSize,
- (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
- cSize.h++;
- NumToString(nowInfo->length, theNumberString);
- LAddToCell(&theNumberString[1], theNumberString[0], cSize,
- (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
- cSize.h++;
-
- LAddToCell(&nowInfo->theType, 4, cSize, (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
- cSize.h++;
-
- LAddToCell(&nowInfo->theName[1], nowInfo->theName[0], cSize,
- (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
-
- cSize.h = 0;
-
- cSize.v++;
-
- /* Here's an additional check I'm adding */
- /* Since I'm using the standard text LDEF, I have a 32k limit on the */
- /* data, so I'm checking the data handle to see if I'm going */
- /* to explode the next pass through */
- if(GetHandleSize((Handle)(*(*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList)->cells) > 30000)
- {
- listErr = kListGrewTooBig;
- break;
- }
- }
- LDoDraw(true, (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
-
- InvalRect(&theWindow->portRect);
- }
- AEDisposeDesc(&theList);
- } else {
- DebugStr("\p didn't find widow with ID ");
- }
- SetPort(tempWP);
- } /* error if else */
- if(listErr)SayError(listErr);
-
- if(nowInfo)
- DisposPtr((Ptr)nowInfo);
-
- return(myErr);
- }
-
- /* Finds the window with this unique ID */
- WindowPtr FindWindowByID(unsigned long askedID)
- {
- WindowPtr currentWP = FrontWindow();
- while (currentWP) {
- windowCHandle tempWCH = (windowCHandle)GetWRefCon(currentWP);
- if ((*tempWCH)->windowID == askedID) {
- break;
- } else {
- currentWP = (WindowPtr)((WindowPeek)currentWP)->nextWindow;
- }
- }
- return(currentWP);
- }
-
- /* AddWindowID */
- /* This adds a unique ID to our documents, so we can always match */
- /* ids to AppleEvent transactions */
- void AddWindowID(WindowPtr theWindow)
- {
- WindowPtr currentWindow;
- windowCHandle tempWCH;
-
- unsigned long theID = TickCount(); /* use tickcount to start */
- Boolean dupedID = false;
- do {
- currentWindow = FrontWindow();
- do {
- if (IsMyWindow(currentWindow)) {
- tempWCH = (windowCHandle)GetWRefCon(currentWindow);
- if ((*tempWCH)->windowID == theID) {
- dupedID = true;
- break;
- }
- }
- currentWindow = (WindowPtr)((WindowPeek)currentWindow)->nextWindow;
-
- }
- while (currentWindow);
-
- if (!dupedID)
- break;
- else /* add 1 and try again */
- theID++;
- }
- while (true);
- tempWCH = (windowCHandle)GetWRefCon(theWindow);
- (*tempWCH)->windowID = theID;
-
- }
-
- void ActivateMain(WindowPtr theWindow,Boolean activate)
- {
- WindowPtr tempWP;
- Rect scratchRect;
- RgnHandle tempRgn;
- windowCHandle tempWCH = (windowCHandle)GetWRefCon(theWindow);
- LActivate(activate, (*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
- GetPort(&tempWP);
- SetPort(theWindow);
- /* make sure the grow box gets drawn dimmed */
- /* clip to the area the grow box is in, and draw it */
- scratchRect = theWindow->portRect;
- scratchRect.top = scratchRect.bottom - 15;
- scratchRect.left = scratchRect.right - 15;
- tempRgn = NewRgn();
- GetClip(tempRgn);
- ClipRect(&scratchRect);
- DrawGrowIcon(theWindow);
- SetClip(tempRgn);
- DisposeRgn(tempRgn);
-
- SetPort(tempWP);
-
- }
- void CloseTheWindow(WindowPtr theWindow)
- {
- windowCHandle tempWCH;
- if (IsMyWindow(theWindow)) {
- tempWCH = (windowCHandle)GetWRefCon(theWindow);
- LDispose((*(documentExtraDataHdl)((*tempWCH)->generalData))->displayList);
- DisposHandle((Handle)tempWCH);
- DisposeWindow(theWindow);
-
- }
- }
-
- void AdjustMenus(void)
- {
- if (IsMyWindow(FrontWindow())) {
- EnableItem(GetMHandle(kFileMenu), kCloseItem);
- EnableItem(GetMHandle(kToolsMenu), 1);
-
- } else {
- DisableItem(GetMHandle(kFileMenu), kCloseItem);
- DisableItem(GetMHandle(kToolsMenu), 1);
-
- }
- EnableItem(GetMHandle(kFileMenu),kNewItem);
- }
-
- void ReDrawGridLines(WindowPtr theWindow, ListHandle theList)
- {
- register qq;
- short cellWide, cellHi;
- cellHi = (*theList)->cellSize.v;
- cellWide = (*theList)->cellSize.h;
-
- /* draw some lines to divide the cells */
- for (qq = 1; qq < 4; qq++) {
- MoveTo(cellWide * qq, kTopLineHeight);
- LineTo(cellWide * qq, theWindow->portRect.bottom - kScrollBarFudge);
- }
- /* now some horriZontal lines */
- for (qq = 0; qq < (((theWindow->portRect.bottom - theWindow->portRect.top) - kTopLineHeight) / cellHi); qq++) {
- MoveTo(0, (cellHi * qq) + kTopLineHeight-1);
-
- LineTo(theWindow->portRect.right - kScrollBarFudge, (cellHi * qq) + kTopLineHeight-1);
- }
- }
-
- void SayError(long longErr)
- {
- Str32 theString;
- Str255 words;
- words[0] = 0;
-
- NumToString(longErr, theString);
- if (longErr == kAppleEventTooBig)
- GetIndString(words, kGeneralStrings, kBigAEWords);
- if (longErr == kListGrewTooBig)
- GetIndString(words, kGeneralStrings, kBigListWords);
-
- ParamText(theString, words, "", "");
- StopAlert(kMDeamonError, nil);
-
- }
-
- pascal Boolean standardDialogFilter(DialogPtr theDialog, EventRecord *theEvent, short *itemHit)
- {
- ModalFilterProcPtr stdProc;
- windowCHandle tempWCH;
- Boolean returnVal = false;
-
- if (theEvent->what == updateEvt && theEvent->message != theDialog) {
- WindowPtr theWindow = (WindowPtr)theEvent->message;
- /* draw my window if it's really mine */
- if (IsMyWindow(theWindow)) {
- tempWCH = (windowCHandle)GetWRefCon(theWindow);
- (ProcPtr)((*tempWCH)->drawMe)(theWindow);
-
-
- *itemHit = 0;
- returnVal = false; /* tell the dialog manager I handled this event */
- }
- } else {
- /* first see if I have an extra filter in */
- if (gExtraDialogFilter)
- returnVal = gExtraDialogFilter(theDialog, theEvent, itemHit);
- if (returnVal == false) {
- GetStdFilterProc(&stdProc);
- returnVal = ((ModalFilterProcPtr)stdProc)(theDialog, theEvent, itemHit);
- }
- }
- return(returnVal);
- }
-
- /* end standardDialogFilter */
-
- pascal Boolean standardAlertFilter(DialogPtr theDialog, EventRecord *theEvent, short *itemHit)
- {
- windowCHandle tempWCH;
- Boolean returnVal = false;
- if (theEvent->what == updateEvt && theEvent->message != theDialog) {
- WindowPtr theWindow = (WindowPtr)theEvent->message;
- /* draw my window if it's really mine */
- /* draw my window if it's really mine */
- if (IsMyWindow(theWindow)) {
- tempWCH = (windowCHandle)GetWRefCon(theWindow);
- ((*tempWCH)->drawMe)(theWindow);
- }
- } else {
- /* for alerts we have to check for keys ourselves, since we didn't have a chance to */
- /* call SetDialogCancel or anything */
-
- if ((theEvent->what == keyDown) || (theEvent->what == autoKey)) {
- short tempItem;
- Handle tempHandle;
- Rect tempRect;
- char theKey = theEvent->message &charCodeMask;
- switch (theKey) {
- long tilticks;
- case kReturnKey:
- case kEnterKey: /* enter key */
- /* This filters for Return or Enter as item 1, and Esc as item 2 */
- *itemHit = 1; /* change whatever the current item is to the OK item */
- /* now we need to invert the button */
- GetDItem(theDialog, 1, &tempItem, &tempHandle, &tempRect);
- if (tempItem == ctrlItem) {
- /* double check for the unlikely event that this is _not_ a button */
- HiliteControl(SnatchHandle(theDialog, ok), inButton);
- Delay(8, &tilticks); /* wait about 8 ticks so they can see it */
- HiliteControl(SnatchHandle(theDialog, ok), false);
-
- returnVal = true;
- }
- break;
- /* This filters the escape key as the same as item 2 (the canx button, usually ) */
- case kEscKey:
- *itemHit = 2;
- if (tempItem == ctrlItem) {
- /* much more likely that this may not be a button */
-
- HiliteControl(SnatchHandle(theDialog, cancel), inButton);
- Delay(8, &tilticks); /* wait about 8 ticks so they can see it */
- HiliteControl(SnatchHandle(theDialog, cancel), false);
- returnVal = true;
- }
- break;
- }
- }
- }
- return(returnVal);
- }
-
- /* end standardDialogFilter */
-
-
-